
module PG(
  input  wire        clk,
  input  wire        rst_n,
  input  wire        clken,
  input  wire [ 4:0] slot,
  input  wire [ 1:0] stage,
  input  wire        rhythm,
  input  wire        pm,
  input  wire [ 3:0] ml,
  input  wire [ 2:0] blk,
  input  wire [ 8:0] fnum,
  input  wire        key,

  output reg         noise,
  output reg  [8:0]  pgout
);

reg         memwr;
reg  [17:0] memin;
wire [17:0] memout;

PhaseMemory U_PhaseMemory(
     .clk  (clk),
     .rst_n(rst_n),
     .slot(slot),
     .memwr(memwr),
     .memout(memout),
     .memin(memin)
);

reg[17:0] lastkey;
always @(posedge clk or negedge rst_n)begin
    if(!rst_n)
	 lastkey <= #1 18'b0;
    else if(stage==2'd2)
	 lastkey[slot] <= #1 key; 
end

reg[12:0] pmcount;
always @(posedge clk or negedge rst_n)begin
    if(!rst_n)
	 pmcount <= #1 13'b0;
    else if((stage==2'd2) && (slot==5'd0))
	 pmcount <= #1 pmcount + 1'b1;
end

always @(posedge clk or negedge rst_n)begin
    if(!rst_n)
        memwr <= #1 1'b0;
    else if(stage==2'd2)
	memwr <= #1 1'b1;
    else
	memwr <= #1 1'b0;
end

reg[4:0] mltlb;
always @(*)begin
    case(ml)
    4'h0: mltlb = 5'b00001;
    4'h1: mltlb = 5'b00010;
    4'h2: mltlb = 5'b00100;
    4'h3: mltlb = 5'b00110;
    4'h4: mltlb = 5'b01000;
    4'h5: mltlb = 5'b01010;
    4'h6: mltlb = 5'b01100;
    4'h7: mltlb = 5'b01110;
    4'h8: mltlb = 5'b10000;
    4'h9: mltlb = 5'b10010;
    4'ha: mltlb = 5'b10100;
    4'hb: mltlb = 5'b10100;
    4'hc: mltlb = 5'b11000;
    4'hd: mltlb = 5'b11000;
    4'he: mltlb = 5'b11000;
    4'hf: mltlb = 5'b11000;
    endcase	    
end

wire[19:0] delta_p = {8'b0, fnum*mltlb} << blk;
reg[17:0] vibrato;
always @(*)begin
    if(pm==1'b0)
	vibrato = 18'b0;
    else
	case(pmcount[12:11])
	2'b01  : vibrato = delta_p>>7;
	2'b11  : vibrato = (~(delta_p>>7)) + 1'b1;
	default: vibrato = 18'b0;
        endcase		
end

reg[17:0] dphase;
always @(posedge clk or negedge rst_n)begin
    if(!rst_n)
	dphase <= #1 18'b0;
    else if(stage==2'd2)
	dphase <= #1 delta_p[19:2] + vibrato; 
end

always @(posedge clk or negedge rst_n)begin
    if(!rst_n)
	memin <= #1 18'b0;
    else if(stage != 2'd2)
	memin <= #1 memin;
    else if((!lastkey[slot]) && key && ((!rhythm) | ((slot!=14) && (slot!=17))))
	memin <= #1 18'b0;
    else
	memin <= #1 memout + dphase;
end

wire[63:0] noise14_table =  64'b1000100010001000100010001000100100010001000100010001000100010000;
wire[ 7:0] noise17_table = 8'b00001010;
reg noise14;
always @(posedge clk or negedge rst_n)begin
    if(!rst_n)
	noise14 <= # 1'b0; 
     else if((stage==2'd2) && (slot==5'd14))
	noise14 <= #1 noise14_table[memout[15:10]];
end

reg noise17;
always @(posedge clk or negedge rst_n)begin
    if(!rst_n)
	noise17 <= #1 1'b0;
    else if((stage==2'd2) && (slot==5'd17))
	noise17 <= #1 noise17_table[memout[13:11]];
end

always@(posedge clk or negedge rst_n)begin
    if(!rst_n)
	pgout <= #1 18'b0;
    else if(stage==2'd2)
	pgout <= #1 memout;
end	

endmodule
